package Model;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.awt.image.ImageProducer;
import java.awt.image.RGBImageFilter;
import java.awt.image.RenderedImage;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Vector;

import javax.imageio.ImageIO;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
import org.apache.batik.util.XMLResourceDescriptor;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import Controleur.Controleur;
import Model.Evenement.CreationEvenement;
import Model.Evenement.Evenement;
import Model.Evenement.SuppressionEvenement;


public class Dessin implements Printable
{
//======================================================================//
//============================ Variables ===============================//
//======================================================================//
	
	private Motif motif; // motif courant
	private Motif pressePapier; // contient un motif si l'utilisateur en a copié un auparavent
	
	private int largeur = 800; // largeur du dessin
	private int hauteur = 600; // hauteur du dessin
	
	private Vector<Motif> motifs = new Vector(); // vecteur de tous les motifs du dessin
	
	private Historique historique = new Historique(); // historique du dessin
	
	private String url = ""; // url du fichier dans laquelle le dessin est enregistré
	private String nom = ""; // nom du dessin
	private float zoom = 1.0f; // zoom du dessin
	private boolean enregistrer = true; // variable qui permet de savoir si le fichier est enregistré ou non
	
	private Color couleur = Color.blue; // couleur courante du dessin
	private Color couleurBordure = Color.black; // couleur courante de la bordure


//======================================================================//
//========================== Constructeurs =============================//
//======================================================================//
	
	/**
	 * Crée une nouvelle instance de <i>Dessin</i> par défaut.
	 */
	public Dessin()
	{
	}
	
	
	/**
	 * Crée une nouvelle instance de <i>Dessin</i> avec les valeurs nom, largeur et hauteur.
	 * 
	 * @param nom Nom du dessin.
	 * @param largeur Largeur du dessin.
	 * @param hauteur Hauteur du dessin.
	 */
	public Dessin(String nom, int largeur, int hauteur)
	{
		this.nom = nom;
		this.largeur = largeur;
		this.hauteur = hauteur;
	}
	
	
	/**
	 * Crée une nouvelle instance de <i>Dessin</i> avec le vecteur de motifs égale à motifs.
	 *
	 * @param motifs Vecteur de motifs.
	 */
	public Dessin(Vector<Motif> motifs)
	{
		this.motifs = motifs;
		
		for(int i = 0; i < this.motifs.size(); i++)
			this.motifs.get(i).setSelectionne(false);
	}
	
	
//======================================================================//
//============================= Méthodes ===============================//
//======================================================================//
	
	/**
	 * Cette méthode permet de créer une nouvelle instance du motif courant en fonction de la demande de l'utilisateur.
	 * 
	 * @param name Nom du nouveau type du motif.
	 * @return Vrai si il y a eu aucun problème, sinon faux.
	 */
	public boolean creationObjet(String name)
	{
		try
		{
			if(this.motif != null)
				this.motif.setSelectionne(false);
			
			Class c = Class.forName("Model."+name);
			this.motif = (Motif) c.newInstance();
			this.motif.setCouleur(this.couleur);
			this.motif.setCouleurBordure(this.couleurBordure);
			
			return true;
		}
		catch(ClassNotFoundException e) {System.out.println("Classe inconnue : "+ e.getMessage());}
		catch(InstantiationException e) {System.out.println("instantiation erreur : " + e.getMessage());}
		catch(IllegalAccessException e) {System.out.println("Classe inconnue : " + e.getMessage());}
		
		return false;
	}
	
	
	/**
	 * Cette méthode permet de savoir si un <i>point</i> est dans un des motifs du dessin.
	 * 
	 * @param point Point que l'on veut savoir si il est dans un des motifs du dessin.
	 * @return Vrai si le <i>point</i> est dans un des motifs du dessin, sinon faux.
	 */
	public boolean find(Point point) 
	{
		Motif motif;
		int i = motifs.size() - 1;
		boolean trouver = false;
		
		while(i >= 0 && !trouver)
		{
			motif = motifs.get(i);
			
			if (motif.contient(point))
			{
				this.motif = motif;
				this.motif.setSelectionne(true);
				
				trouver = true;
			}
			
			i--;
		}
		
		if(!trouver)
			this.motif = null;

		return trouver;
	}
	
	
	/**
	 * Cette méthode permet de supprimer une motif du dessin, si le <i>point</i> est dans un des motifs du dessin.
	 * 
	 * @param point Point que l'on veut savoir si il est dans un des motifs du dessin pour pouvoir le supprimer.
	 * @return Le motif qui a été supprimé.
	 */
	public Motif effacerMotif(Point point)
	{
		Motif motif = null;
		int i = this.motifs.size() - 1;
		boolean trouver = false;
		
		while(i >= 0 && !trouver)
		{
			motif = this.motifs.get(i);
			
			if(this.motifs.get(i).contient(point))
			{
				motif = this.motifs.get(i);	
				this.motifs.remove(i);
				trouver = true;
			}
			
			i--;
		}
		
		return motif;
	}

	
	/**
	 * Cette méthode permet de dessiner le motif courant dans la fenêtre.
	 * 
	 * @param g Variable permettant de dessiner dans une fenêtre.
	 */
	public void dessiner(Graphics2D g)
	{
		if(this.motif != null)
			this.motif.dessiner(g);
	}
	
	
	/**
	 * Cette méthode permet de dessiner tous les motifs du dessin dans la fenêtre.
	 * 
	 * @param g Variable permettant de dessiner dans une fenêtre.
	 */
	public void toutDessiner(Graphics2D g) 
	{
		for(int i = 0; i < this.motifs.size(); i++)
		{
			this.motifs.get(i).dessiner(g);	
		}
	}
	
	
	/**
	 * Cette méthode permet d'entregistrer un dessin dans un fichier. 
	 * 
	 * @param enregistrerSous 
	 * @return Vrai si le dessin a réussi à s'enregistrer, sinon faux.
	 */
	public boolean enregistrer(boolean enregistrerSous) 
	{
		try 
		{
			DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
	        DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
	        Document doc = docBuilder.newDocument();
	
	
	        Element root = doc.createElement("svg");
	        root.setAttribute("xmlns:svg", "http://www.w3.org/2000/svg");
	        root.setAttribute("xmlns", "http://www.w3.org/2000/svg");
	        root.setAttribute("version", "1.1");
	        root.setAttribute("width", ""+this.largeur);
	        root.setAttribute("height", ""+this.hauteur);
	        doc.appendChild(root);
	        
			for(int i = 0; i < this.motifs.size(); i++)
			{
				 Element child = this.motifs.get(i).enregistrer(doc);
		         root.appendChild(child);
			}
			
	
			TransformerFactory transfac = TransformerFactory.newInstance();
			Transformer trans;
	
			trans = transfac.newTransformer();
	
			trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
			trans.setOutputProperty(OutputKeys.INDENT, "yes");
			trans.setOutputProperty(OutputKeys.ENCODING, "utf-8");
	
			StringWriter sw = new StringWriter();
			StreamResult result = new StreamResult(sw);
			DOMSource source = new DOMSource(doc);
			trans.transform(source, result);
			String xmlString = sw.toString();
	
	
			if(this.url == "" || enregistrerSous)
			{
				boolean changerTitreFenetre = this.nom == "Sans titre";
				JFileChooser chooser = new JFileChooser();
	
				MonFiltre filtre = new MonFiltre("Fichier SVG", ".svg");
	
				chooser.addChoosableFileFilter(filtre);
				int valeurRetour = chooser.showSaveDialog(chooser.getParent());
	
				if(valeurRetour == JFileChooser.APPROVE_OPTION) 
				{
					String url = chooser.getSelectedFile().getAbsolutePath();
					this.decouperURL(url);
	
					try
					{
						FileWriter t;
						t = new FileWriter(this.url+""+this.nom+".svg");
						t.write(xmlString);
						t.close();
	
						this.enregistrer = true;
						return true;
					}
					catch (IOException e) {e.printStackTrace();}				
				}
			}
			else
			{
				try
				{
					FileWriter t;
					t = new FileWriter(this.url+""+this.nom+".svg");
					t.write(xmlString);
					t.close();
	
					this.enregistrer = true;
					return true;
				}
				catch (IOException e) {e.printStackTrace();}
			}
		}
		catch (TransformerConfigurationException e1) {e1.printStackTrace();}
		catch (TransformerException e) {e.printStackTrace();}
		catch (ParserConfigurationException e) {e.printStackTrace();}

		return false;
	}
	
	
	/**
	 * Cette méthode permet de diviser une url d'un fichier en deux (url et le nom).
	 * 
	 * @param url L'url du fichier.
	 */
	public void decouperURL(String url)
	{
		String url1 = "", nom ="";
		String str1[] = url.split("/");
		
		for(int i = 0; i < str1.length - 1; i++)
			url1 += str1[i]+"/";
		
		String str2[] = str1[str1.length - 1].split("\\.");
		
		for(int i = 0; i < str2.length - 1; i++)
			nom += str2[i]+".";
		
		if(!str2[str2.length - 1].equals("svg"))
			nom += str2[str2.length - 1];
		else
			nom = nom.substring(0, nom.length() - 1);
		
		this.nom = nom;
		this.url = url1;
	}
	
	
	/**
	 * Cette méthode permet d'ouvrir un fichier est de le convertir en <i>Dessin</i>.
	 */
	public void ouvrir() 
	{
		JFileChooser chooser = new JFileChooser();
		MonFiltre filtre = new MonFiltre("Fichier SVG", ".svg");
		chooser.addChoosableFileFilter(filtre);

		int valeurRetour = chooser.showOpenDialog(chooser.getParent());
    
		if(valeurRetour == JFileChooser.APPROVE_OPTION) 
		{
			try 
			{
				File fichier = chooser.getSelectedFile();
				
				String parser = XMLResourceDescriptor.getXMLParserClassName();
				SAXSVGDocumentFactory documentF = new SAXSVGDocumentFactory(parser);
				this.decouperURL(fichier.toURL().toString());
       
				Document doc = documentF.createDocument(this.url+""+this.nom+".svg");
				
				this.url = this.url.substring(5);
				this.motifs.removeAllElements();
				
				Node node = doc.getFirstChild();
				
				if(node.getNodeName() == "svg")
				{
					Node attribut;
					
					for(int j = 0; j < node.getAttributes().getLength(); j++)
					{			
						attribut = node.getAttributes().item(j);
						
						if(attribut.getNodeName() == "width")
							this.largeur = Integer.valueOf(attribut.getNodeValue());
						else if(attribut.getNodeName() == "height")
							this.hauteur = Integer.valueOf(attribut.getNodeValue());							
					}
				}
				
				this.parcours(doc.getFirstChild().getChildNodes());
				
				this.enregistrer = true;
			} 
			catch (IOException e1) {e1.printStackTrace();}
		} 
	}
	
	
	/**
	 * Cette méthode permet de parcourir une ligne d'un fichier xml et de la convertir en différent <i>Motif</i>.
	 * 
	 * @param nodes Ligne d'un fichier xml.
	 */
	public void parcours(NodeList nodes)
	{
		Node node;
		Boolean trouver;
		Motif motif = new Rectangle();
		
		for(int i = 0; i < nodes.getLength(); i++)
		{
			node = nodes.item(i);
			trouver = false;
			
			if(node.getChildNodes().getLength() < 2)
			{	
				if(node.getNodeName() == "rect")
				{		
					motif = new Rectangle();
					trouver = true;
				}
				else if(node.getNodeName() == "ellipse")
				{
					motif = new Ellipse();
					trouver = true;
				}
				else if(node.getNodeName() == "line")
				{
					motif = new Ligne();
					trouver = true;
				}
				else if(node.getNodeName() == "polygon")
				{
					motif = new Polygone();
					trouver = true;
				}
				else if(node.getNodeName() == "text")
				{
					motif = new Texte();
					trouver = true;
				}
				
				if(trouver)
				{
					motif.ouvrir(node);					
					this.ajouterMotif(motif);
				}
			}
			else
				this.parcours(node.getChildNodes());
		}
	}
	
	
	/**
	 * Cette méthode permet d'exporter un dessin sous un autre format.
	 * 
	 * @param extension Format dans lequel le dessin sera enregistre.
	 */
	public void exporter(String extension)
	{
		BufferedImage bufferedImage = new BufferedImage(this.largeur, this.hauteur, BufferedImage.TYPE_INT_ARGB);

	    Graphics2D g2d = (Graphics2D) bufferedImage.getGraphics();
	    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

	    this.toutDessiner(g2d); 	    
	    g2d.dispose();

	    File file = new File(this.url +""+this.nom+"."+ extension);
	    
	    try
		{
			ImageIO.write(bufferedImage, extension, file);
		}
		catch (IOException e){ e.printStackTrace();	}
	}
	
	
	@Override
	public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException
	{
		 if(pageIndex > 0) 
			 return NO_SUCH_PAGE;
	     
		 Graphics2D g2d = (Graphics2D) graphics;
	     g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
	     g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
	     
	     this.toutDessiner(g2d);
	     
	     return PAGE_EXISTS;
	} 
	
	class MonFiltre extends FileFilter 
	{
		private String description;
		private String extension;
	  
		public MonFiltre(String description, String extension)
		{
			if(description == null || extension == null)
				throw new NullPointerException("La description (ou extension) ne peut ?tre null.");
	      
			this.description = description;
			this.extension = extension;
		}
	  
		public boolean accept(File file) 
		{
			if(file.isDirectory()) 
				return true; 
 
			String nomFichier = file.getName().toLowerCase(); 

			return nomFichier.endsWith(extension);
		}

		public String getDescription() 
		{
			return this.description;
		}
	}
	
	
	@Override
	public String toString()
	{
		String texte = "";
		
		for (int i = 0; i < this.motifs.size(); i++)
		{
			texte += this.motifs.get(i).toString();
		}
	
		return texte;
	}
	
	
	/**
	 * Cette méthode permet d'ajouter un <i>Motif</i> dans le dessin. 
	 * 
	 * @param motifSelectionne Nouveau <i>Motif</i>.
	 */
	public void ajouterMotif(Motif motifSelectionne)
	{
		this.motif = motifSelectionne;
		this.motifs.add(motifSelectionne);
	}
	

	/**
	 * Cette méthode permet de supprimer un <i>Motif</i> du dessin grâce à <i>indice</i>. 
	 * 
	 * @param indice Indice du motif que l'on veut supprimer.
	 */
	public void supprimerMotif(int indice)
	{
		this.motifs.remove(indice);
	}
	
	
	/**
	 * Cette méthode permet de supprimer un <i>Motif</i> du dessin grâce à <i>motif</i>. 
	 * 
	 * @param motif Motif que l'on veut supprimer.
	 */
	public void supprimerMotif(Motif motif)
	{
		this.motifs.remove(motif);
	}
	
	
	/**
	 * Cette méthode permet de savoir si le dessin est enregistré.
	 * 
	 * @return Vrai si le dessin est enregistrer, sinon faux.
	 */
	public boolean estEnregistrer()
	{
		return this.enregistrer;
	}
	
	
	/**
	 * Cette méthode permet de dézoomer dans le dessin.
	 */
	public void zoomOut()
	{
		this.zoom -= 1.0f;
	}
	
	
	/**
	 * Cette méthode permet de zoomer dans le dessin.
	 */
	public void zoomIn()
	{
		this.zoom += 1.0f;
	}
	
	
	/**
	 * Cette permet de savoir si il y a aucun <i>Motif</i> dans le dessin.
	 * 
	 * @return Vrai si il y a aucun <i>Motif</i> dans le dessin, sinon faux.
	 */
	public boolean motifsEstVide()
	{		
		return this.motifs.isEmpty();
	}
	
	
	/**
	 * Cette méthode permet d'ajouter un <i>Motif</i> dans le dessin. 
	 */
	public void ajouterMotif()
	{
		this.motifs.add(this.motif);
	}
	
	
	/**
	 * Cette méthode permet de remplacer <i>motifAModifier</i> du dessin par <i>motifModifier</i>.
	 * 
	 * @param motifAModifier Motif que l'on veut modifier.
	 * @param motifModifier Nouveau motif.
	 */
	public void remplaceMotif(Motif motifAModifier, Motif motifModifier)
	{
		int i = 0;
		int indice = -1;
		boolean trouver = false;
		
		while(i < this.motifs.size() && !trouver)
		{
			if(this.motifs.elementAt(i).equals(motifAModifier))
			{
				indice = i;
				trouver = true;
			}
			
			i++;
		}
		
		this.motifs.set(indice, motifModifier.clone());	
	}
	
	
	/**
	 * Cette méthode permet de trouver si <i>motif</i> est present dans dessin.
	 * 
	 * @param motif motif à trouver.
	 */
	public boolean trouverMotif(Motif motif)
	{
		int i = 0;
		boolean trouver = false;
		
		while(i < this.motifs.size() && !trouver)
		{
			if(this.motifs.elementAt(i).equals(motif))
			{
				trouver = true;
			}
			i++;
		}
		return trouver;
	}

//======================================================================//
//========================= Getters et Setters =========================//
//======================================================================//	

	/**
	 * Retourne le motif courant du <i>Dessin</i>.
	 *
	 * @return motif Le motif courant du <i>Dessin</i>.
	 */
	public Motif getMotif()
	{
		return motif;
	}


	/**
	 * Cette méthode permet de modifier la valeur du motif courant.
	 *
	 * @param motif Nouvelle valeur de <i>motif</i>.
	 */
	public void setMotif(Motif motif)
	{
		this.motif = motif;
	}


	/**
	 * Retourne la largeur du <i>Dessin</i>.
	 *
	 * @return largeur La largeur du <i>Dessin</i>.
	 */
	public int getLargeur()
	{
		return largeur;
	}


	/**
	 * Cette méthode permet de modifier la largeur du <i>Dessin</i>.
	 *
	 * @param largeur Nouvelle valeur de <i>largeur</i>.
	 */
	public void setLargeur(int largeur)
	{
		this.largeur = largeur;
	}


	/**
	 * Retourne la hauteur du <i>Dessin</i>.
	 *
	 * @return hauteur La hauteur du <i>Dessin</i>.
	 */
	public int getHauteur()
	{
		return hauteur;
	}


	/**
	 * Cette méthode permet de modifier la hauteur du <i>Dessin</i>.
	 *
	 * @param hauteur Nouvelle valeur de <i>hauteur</i>.
	 */
	public void setHauteur(int hauteur)
	{
		this.hauteur = hauteur;
	}


	/**
	 * Retourne tous les motifs du <i>Dessin</i>.
	 *
	 * @return motifs Tous les motifs du <i>Dessin</i>.
	 */
	public Vector<Motif> getMotifs()
	{
		return motifs;
	}


	/**
	 * Cette méthode permet de modifier le vecteur de motifs du <i>Dessin</i>.
	 *
	 * @param motifs Nouvelle valeur de <i>motifs</i>.
	 */
	public void setMotifs(Vector<Motif> motifs)
	{
		this.motifs = motifs;
	}


	/**
	 * Retourne l'historique du <i>Dessin</i>.
	 *
	 * @return historique L'historique du <i>Dessin</i>.
	 */
	public Historique getHistorique()
	{
		return historique;
	}


	/**
	 * Cette méthode permet de modifier l'historique du <i>Dessin</i>.
	 *
	 * @param historique Nouvelle valeur de <i>historique</i>.
	 */
	public void setHistorique(Historique historique)
	{
		this.historique = historique;
	}


	/**
	 * Retourne l'url où est enregistrer le dessin.
	 *
	 * @return url L'url où est enregistrer le dessin.
	 */
	public String getUrl()
	{
		return url;
	}


	/**
	 * Cette méthode permet de modifier url où est enregistrer le dessin.
	 *
	 * @param url Nouvelle valeur de <i>url</i>.
	 */
	public void setUrl(String url)
	{
		this.url = url;
	}


	/**
	 * Retourne le zoom du <i>Dessin</i>.
	 *
	 * @return zoom Le zoom du <i>Dessin</i>.
	 */
	public float getZoom()
	{
		return zoom;
	}


	/**
	 * Cette méthode permet de modifier le zoom du <i>Dessin</i>.
	 *
	 * @param zoom Nouvelle valeur de <i>zoom</i>.
	 */
	public void setZoom(float zoom)
	{
		this.zoom = zoom;
	}


	/**
	 * Retourne vrai si le dessin est enregistrer, sinon faux.
	 *
	 * @return enregistrer Vrai si le dessin est enregistrer, sinon faux.
	 */
	public boolean isEnregistrer()
	{
		return enregistrer;
	}


	/**
	 * Cette méthode permet de modifier la valeur de <i>enregistrer</i>.
	 *
	 * @param enregistrer Nouvelle valeur de <i>enregistrer</i>.
	 */
	public void setEnregistrer(boolean enregistrer)
	{
		this.enregistrer = enregistrer;
	}


	/**
	 * Retourne la couleur du <i>Dessin</i>.
	 *
	 * @return couleur La couleur du <i>Dessin</i>.
	 */
	public Color getCouleur()
	{
		return couleur;
	}


	/**
	 * Cette méthode permet de modifier la couleur du <i>Dessin</i>.
	 *
	 * @param couleur Nouvelle valeur de <i>couleur</i>.
	 */
	public void setCouleur(Color couleur)
	{
		this.couleur = couleur;
	}


	/**
	 * Retourne la couleur de la bordure du <i>Dessin</i>.
	 *
	 * @return couleurBordure La couleur de la bordure du <i>Dessin</i>.
	 */
	public Color getCouleurBordure()
	{
		return couleurBordure;
	}


	/**
	 * Cette méthode permet de modifier la couleur de la bordure du <i>Dessin</i>.
	 *
	 * @param couleurBordure Nouvelle valeur de <i>couleurBordure</i>.
	 */
	public void setCouleurBordure(Color couleurBordure)
	{
		this.couleurBordure = couleurBordure;
	}


	/**
	 * Retourne le nom du dessin
	 *
	 * @return nom Le nom du dessin.
	 */
	public String getNom()
	{
		return nom;
	}


	/**
	 * Cette méthode permet de modifier le nom du dessin.
	 *
	 * @param nom Nouvelle valeur de <i>nom</i>.
	 */
	public void setNom(String nom)
	{
		this.nom = nom;
	}

	/**
	 * Cette méthode permet de copier le motif courant.
	 *
	 */
	public void copier() 
	{
		pressePapier = motif.clone();
	} 
	
	/**
	 * Cette méthode permet de couier le motif courant.
	 *
	 */
	public void couper() 
	{
		pressePapier = motif.clone();
		Evenement e = new SuppressionEvenement(this, pressePapier);
		historique.ajouterEvenement(e);
		e.executer();
		
		setEnregistrer(false);
		historique.supprimerHistoriqueRetablir();
	} 
	/**
	 * Cette méthode permet de coller le motif courant.
	 *
	 */
	public void coller() 
	{
		if(pressePapier != null)
		{
			motif.setSelectionne(false);
			pressePapier.setSelectionne(true);
			Evenement e = new CreationEvenement(this, pressePapier);
			historique.ajouterEvenement(e);
			e.executer();

			setEnregistrer(false);
			historique.supprimerHistoriqueRetablir();
		}

	} 
}